{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. 决策树\n",
    "sklearn.tree.DecisionTreeClassifier()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.1 简单例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn import tree"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = [[0, 0], [1, 1]]\n",
    "Y = [0, 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "dt_test_clf = tree.DecisionTreeClassifier()\n",
    "dt_test_clf = dt_test_clf.fit(X, Y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dt_test_clf.predict([[2., 2.]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0., 1.]])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dt_test_clf.predict_proba([[2., 2.]])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.2 iris数据集\n",
    "### 1.2.1 训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.datasets import load_iris\n",
    "from sklearn import tree"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "iris = load_iris()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "dt_clf = tree.DecisionTreeClassifier()\n",
    "dt_clf = dt_clf.fit(iris.data, iris.target)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2.2 模型预测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
       "       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
       "       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n",
       "       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n",
       "       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_pred = dt_clf.predict(iris.data)\n",
    "y_pred"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2.3 绘图"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对于scikit-learn 0.21.2版本以上，可以采用以下命令绘图：\n",
    "> tree.plot_tree(clf.fit(iris.data, iris.target)) \n",
    "\n",
    "这里默认scikit-learn版本为0.19.1，需要按如下步骤安装graphviz包：\n",
    "1. 下载安装 graphviz-2.38.msi, \n",
    "2. 将安装路径下的bin文件夹加入系统路径PATH（默认路径为C:\\Program Files (x86)\\Graphviz2.38\\bin）\n",
    "3. 在命令提示行输入以下命令：\n",
    "> pip install graphviz"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "import graphviz"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'iris.pdf'"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dot_data = tree.export_graphviz(dt_clf, out_file=None) \n",
    "graph = graphviz.Source(dot_data) \n",
    "graph.render(\"iris\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'iris.pdf'"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph.view()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. 朴素贝叶斯\n",
    "sklearn.naive_bayes.GaussianNB()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn import datasets\n",
    "from sklearn.naive_bayes import GaussianNB"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "iris = datasets.load_iris()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "gnb = GaussianNB()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GaussianNB(priors=None)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 训练模型\n",
    "gnb.fit(iris.data, iris.target)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 进行预测\n",
    "y_pred = gnb.predict(iris.data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
       "       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
       "       0, 0, 0, 0, 0, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,\n",
       "       2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n",
       "       2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_pred"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. K近临分类\n",
    "sklearn.neighbors.KNeighborsClassifier()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn import neighbors, datasets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "iris = datasets.load_iris()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 指定近邻个数\n",
    "n_neighbors = 15"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=1, n_neighbors=15, p=2,\n",
       "           weights='distance')"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# weights 可选：'uniform', 'distance'\n",
    "weights = 'distance' \n",
    "knn_clf = neighbors.KNeighborsClassifier(n_neighbors, weights=weights)\n",
    "knn_clf.fit(iris.data, iris.target)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "knn_pre_y = knn_clf.predict(iris.data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
       "       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
       "       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n",
       "       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n",
       "       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn_pre_y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. 模型评价"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 准备数据+训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from scipy import interp\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from sklearn import svm, datasets\n",
    "from sklearn import metrics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 准备数据\n",
    "iris = datasets.load_iris()\n",
    "X = iris.data\n",
    "y = iris.target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "100"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 取出第一类和第二类\n",
    "X, y = X[y != 2], y[y != 2]\n",
    "n_samples, n_features = X.shape\n",
    "n_samples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 加入噪声特征\n",
    "random_state = np.random.RandomState(0)\n",
    "X = np.c_[X, random_state.randn(n_samples, 200 * n_features)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 随机选取80个样本作为训练集，其余作为测试集\n",
    "t = np.array(range(100))\n",
    "np.random.shuffle(t)\n",
    "train_idx = t >= 20\n",
    "\n",
    "train_X = X[train_idx,:]\n",
    "train_y = y[train_idx]\n",
    "text_X = X[~train_idx,:]\n",
    "test_y= y[~train_idx]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "svc_clf = svm.SVC(kernel='linear', probability=True,\n",
    "                 random_state=random_state)\n",
    "svc_clf = svc_clf.fit(train_X, train_y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.1 准确率\n",
    "sklearn.metrics.accuracy_score()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pre = svc_clf.predict(text_X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "metrics.accuracy_score(test_y,y_pre)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.2 混淆矩阵\n",
    "sklearn.metrics.confusion_matrix()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[7 3]\n",
      " [5 5]]\n"
     ]
    }
   ],
   "source": [
    "cnf_matrix = metrics.confusion_matrix(test_y, y_pre)\n",
    "print(cnf_matrix)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## 4.3 ROC曲线\n",
    "sklearn.metrics.roc_curve()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import roc_curve, auc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "tprs = []\n",
    "aucs = []\n",
    "mean_fpr = np.linspace(0, 1, 100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x2a66b25e3c8>]"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "probas_ = svc_clf.predict_proba(text_X)\n",
    "fpr, tpr, thresholds = roc_curve(test_y, probas_[:, 1])\n",
    "tprs.append(interp(mean_fpr, fpr, tpr))\n",
    "tprs[-1][0] = 0.0\n",
    "roc_auc = auc(fpr, tpr)\n",
    "aucs.append(roc_auc)\n",
    "plt.plot(fpr, tpr, lw=1, alpha=0.3,\n",
    "         label='ROC Curve (AUC = %0.2f)' % roc_auc)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.4 交叉验证与ROC曲线"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from scipy import interp\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from sklearn import svm, datasets\n",
    "from sklearn.metrics import roc_curve, auc\n",
    "from sklearn.model_selection import StratifiedKFold"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 载入数据 只取第一类和第二类\n",
    "iris = datasets.load_iris()\n",
    "X = iris.data\n",
    "y = iris.target\n",
    "X, y = X[y != 2], y[y != 2]\n",
    "n_samples, n_features = X.shape\n",
    "\n",
    "# Add noisy features\n",
    "random_state = np.random.RandomState(0)\n",
    "X = np.c_[X, random_state.randn(n_samples, 200 * n_features)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 采用交叉验证的方式训练模型\n",
    "cv = StratifiedKFold(n_splits=5)\n",
    "classifier = svm.SVC(kernel='linear', probability=True,\n",
    "                     random_state=random_state)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYUAAAEWCAYAAACJ0YulAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzsnXl4FFXWh9+TPZAQdmURWcMOAQOCI4KKyiCL4IJ8CjqoOIrgOooC6igjjDqiKKKIyqiYoCjCKIwLiwqOCsguQgiyBRBIgOxLd9/vj9vddJJO6JB09Vbv8/ST1NJ1T1V316l7zj2/K0opTExMTExMAMJ8bYCJiYmJif9gOgUTExMTEyemUzAxMTExcWI6BRMTExMTJ6ZTMDExMTFxYjoFExMTExMnplMwqTIicouIfOVrO3yNiLQQkVwRCTewzZYiokQkwqg2vYmI7BCRAefwPvM76CXErFMIbERkH3AeYAVygf8C9ymlcn1pVzBiv9Z3KqW+8aENLYHfgUillMVXdthtUUA7pdQeL7fTEj8551DA7CkEB0OVUnFAEtADeNzH9pwTvnz6DZYn76pgXm8Td5hOIYhQSh0FvkQ7BwBEJFpEXhSRAyLyh4i8ISKxLtuHi8hmEckWkXQRGWRfnyAib4vIERHJEJHpjjCJiNwuImvt/78hIi+62iEiS0XkIfv/TUXkExE5LiK/i8gkl/2eFpHFIvKBiGQDt5c9J7sd79nfv19EpopImIsd60TkVRE5LSK/iciVZd5b2TmsE5FZIpIFPC0ibURklYhkisgJEVkoInXt+78PtAD+Yw8ZPVo2lCMia0TkWftxc0TkKxFp6GLPWPs5ZIrINBHZJyID3X2WIhIrIv+y739aRNa6fm7ALfbP9ISITHF5X28R+Z+InLKf92siEuWyXYnIBBFJA9Ls614RkYP278BGEennsn+4iDxh/27k2LdfICLf2XfZYr8eo+z7D7F/n06JyA8i0s3lWPtE5DER2QrkiUiE6zWw277BbscfIvKS/a2Otk7Z2+rr+h20v7eziHwtIln29z7h7rqaeIBSynwF8AvYBwy0/98c2Aa84rL9ZWAZUB+IB/4DzLBv6w2cBq5CPyA0AzrYt30GvAnUBhoDPwN327fdDqy1/38ZcJAzoch6QAHQ1H7MjcCTQBTQGtgLXGPf92mgBLjOvm+sm/N7D1hqt70lsBu4w8UOC/AgEAmMsp9PfQ/PwQJMBCKAWKCt/VpEA43QN6OX3V1r+3JLQAER9uU1QDqQaD/eGmCmfVsndHjvUvu1eNF+7gMr+Fzn2N/fDAgHLrHb5WjzLXsb3YEioKP9fRcBfezn1BLYCTzgclwFfI3+PsTa190KNLC/52HgKBBj3/Y39HeqPSD29hq4HKuty7F7AseAi+0232a/ZtEu128zcIFL285rCvwPGGP/Pw7o4+46u/kOxgNH7LbH2Jcv9vVvM1BfPjfAfFXzA9Q/qlwgx/7DWQnUtW8TIA9o47J/X+B3+/9vArPcHPM8+40m1mXdaGC1/X/XH6QAB4DL7Mt3Aavs/18MHChz7MeBd+3/Pw18V8m5hdvt6OSy7m5gjYsdh7E7JPu6n4ExHp7DgYratu9zHbCpzLU+m1OY6rL9XuC/9v+fBFJcttUCinHjFNAOsgDo7mabo83mZc755grO4QFgicuyAq44y3mfdLQN7AKGV7BfWacwF3i2zD67gP4u12+cm++vwyl8B/wdaFjBOVfkFEa7fk7mq3ovM64XHFynlPpGRPoDHwINgVPop91awEYRcewr6Jst6Ce25W6OdyH6yfuIy/vC0D2CUiillIikon+Y3wH/B3zgcpymInLK5S3hwPcuy+WO6UJD9FP1fpd1+9FPzw4ylP3O4LK9qYfnUKptEWkMzAb6oZ82w9A3yKpw1OX/fPQTL3abnO0ppfJFJLOCYzREP/GmV7UdEUkEXgKS0Z99BLq35krZ834YuNNuowLq2G0A/R2pzA5XLgRuE5GJLuui7Md123YZ7gCeAX4Tkd+BvyulPveg3arYaHIWzJxCEKGU+hZYgA5NAJxAP3F2VkrVtb8SlE5Kg/6BtnFzqIPop+yGLu+ro5TqXEHTKcANInIhunfwictxfnc5Rl2lVLxSarCr2ZWc0gl0iOVCl3UtgAyX5Wbicte3bz/s4TmUbXuGfV03pVQddFhFKtm/KhxBh/cAnTNAh2zccQIoxP1nczbmAr+hRwXVAZ6g9DmAy3nY8wePATcB9ZRSddEhOMd7KvqOuOMg8I8yn3ctpVSKu7bLopRKU0qNRof6/gksFpHalb3nHGw0OQumUwg+XgauEpEkpZQNHXueZX8KRkSaicg19n3fBv4iIleKSJh9Wwel1BHgK+BfIlLHvq2NvSdSDqXUJuA4MB/4Uinl6Bn8DGTbk4ux9qRlFxHp5cmJKKWswEfAP0Qk3u50HuJMTwT0DWSSiESKyI1AR2B5Vc/BTjw6FHdKRJqh4+mu/IHOi5wLi4GhInKJPfH7d8rfrAGwf27vAC+JTtSH25Or0R60Ew9kA7ki0gG4x4P9LejPL0JEnkT3FBzMB54VkXai6SYiDmdW9nq8BfxVRC6271tbRK4VkXgP7EZEbhWRRvbzd3yHrHbbbFR87T8HzheRB0QPrIgXkYs9adOkPKZTCDKUUsfRydlp9lWPAXuAH0WP8PkGnTREKfUz8BdgFvrp8FvOPJWPRXf9f0WHUBYDTSppOgUYiA5fOWyxAkPRo6F+Rz8BzwcSqnBKE9F5kb3AWvvx33HZ/hPQzn7sfwA3KKUcYZmqnsPf0cnS08AXwKdlts8AptpH1jxShXNAKbXDfi6p6F5DDjopW1TBWx5BJ3jXA1noJ2dPfq+PoEN4Oeib9KKz7P8lsAKdwN+P7qG4hnheQjvmr9DO5m10ght0Tujf9utxk1JqAzqn9Br6eu/BzYiyShgE7BCRXOAVdJ6kUCmVj/5s19nb6uP6JqVUDnqAwFB0WC0NuLwK7Zq4YBavmQQsInI7upjsUl/bUlVEJA79NNxOKfW7r+0xMXFg9hRMTAxCRIaKSC17nPxFdE9gn2+tMjEpjekUTEyMYzg6CX4YHfK6WZlddRM/wwwfmZiYmJg4MXsKJiYmJiZOAq54rWHDhqply5a+NsPExMQkoNi4ceMJpVSjs+0XcE6hZcuWbNiwwddmmJiYmAQUIrL/7HuZ4SMTExMTExdMp2BiYmJi4sR0CiYmJiYmTkynYGJiYmLixHQKJiYmJiZOvOYUROQdETkmItsr2C4iMltE9ojIVhHp6S1bTExMTEw8w5s9hQVo1cOK+DO61L8dMB6tA29iYmJi4kO8VqeglPpORFpWsstw4D279suPIlJXRJrYdfBNTExMzso338DHH4PN5mtLvMzJkxAWRq+BCYwf792mfFm81ozSuu2H7OvKOQURGY/uTdCiRQtDjAsWln/7HVaL1ddmhAT7svKwWm0UFxUTKppicfmH0PPfGM+JjbH8e8UwlHI7V1HQEJOXR3RhAdbwCP44tInx4wd4tT1fOgV3n6TbX5JSah4wDyA5OTk0fm01hNViZeiV5nwjRvD1jiN0TLBSWFhIZGSkr80xhNgD+RS0GGB4u5mZYUx6I5K4hvUYNCiHIUNiKD0ra/AQsfgbIr76CsvVV9Ng/I3eb8/rLVTMIfSE2w6aoyWFTUwCDpvNxsmTpyiMjqRWrVq+NscwwiMiDHeAFgu88EIC2XlFdO1TzIQJhVx4YUNDbfAqOTmQkQEdOujl3jfDPRefWfYyvnQKy4D7RCQVPdn7aTOfYFJT5OXlUVxcbFh7+fn5FBUXUatWVWYaDQ7S08OZOzeOwkJjntQLCoTDh8NpkJDNQw+dpm7d+oa0awjffgszZkBYGHz0EcTFQXS0YQ4BvOgURCQFGAA0FJFDwFNAJIBS6g1gOTAYPY9rPnquYBOTamO1Wjly5Iih4YSwsDCio6INa8+fWLYslh07jO0tREcrHhu1nYSEVkRHB8F1z8qCF1+Er77Sy1276h5DXJzhpnhz9NHos2xXwARvtW8SumRnZwMQGxt7lj1rmkKD2/M9SsHmzVEAPP54Nk2bGpN0btzYSsy201hFAtspKAUrVmiHkJ0NMTEwYQKMGqV7Cz4g4KSzTUwqw2q1kpWVRUxMjK9NCQmOnojl2LEw4uIUl15abOh9rMBqITY2NrATzDNmwKef6v9794apU6FpU5+aZDoFk6AiOzsbpRRhPnrKCjU2/doAgO7dSwx/sLVabcT5ILxSowwYAF9/DQ8+CEOHgh84ONMpBDk2pTh9+jQ2A6t7oqKiiI2NNfzGbPYSjOeXndopdOtmXFLflYALHR04AOvXw/XX6+VLLoH//McnuYOKMJ1CkGOzWTl69CgREcZ91EopRIQ6deoYGtcvKCgwewkGohRstjuFHj1KDG3bZrMhoh9AAgKrFRYuhDfegJISSEzUyWTwK4cAplMIepSC8PBww5OuNpuNnJwcTp06ZVibImL2EgzkwIFwTuZEUP98G82bG1s1X1JSQnRMgBSs7d4Nzz4LO3fq5WuvBT9WZjCdQpCjlG8kCMLCwswbdJCzeXMkoOjevcTwULjVaqV2tJ9/v4qL4e23YcEC3VM4/3x44gkdMvJjTKcQ5ISIBI+JD9BDUYtISiqmsLAQq9W43kJYWBhRUX4uJfLaa/Dhh/r/m26C++6DAKh2N51CkOOrnoJJcGOzwbZtkUAR3buXYLVaadKkiaFhyvz9Bwxr65y47TbYtg0mTYIePXxtjceYTiHIsdnMxKtJzbNnTwR5eULThvmcd144+flCZGQk4eHhvjbNd/z0E3zyia49CA+HBg3gnXf8YphpVTCdQpCjR2kE1pfSpOpkZIQxY0Ydjhwx5qZcUqK/Uz07ZQKNUUoZOsLNr8jOhpdfhmXL9PKyZTBihP4/AH97Ifophg5KmU4h2CkogOnTE9i3z9in9IgIuPziIyjVCBEJzR7p6tUwcyZkZkJUFNx1ly5CC2BMpxDkKDN8FNQoBa+9Fs++feE0a2bl+edPEx1tzOiCyEhF/JEs8qxWoqKiQuvhIzMTnn8eVq7Uy926wZNPQsuWPjWrJjCdQpBjsxeSmQQnn38ew6pV0URHK6ZNy6Z+feMHFthsttAbfvztt9ohxMbCxIlwww0+E7CraUynEOTYbFbTKRjIk0/WYeNG46psHeolDzyQy4UX+mbaVau9pxD0FBfrEBHAddfBoUPaGfhYwK6mMZ1CEKOUQinM8JFB5OeFsX69sTfH8HAYNSqfAQOKDG3XQdG2dCy1wVqvHjkxxlbNS6RBty+bDRYvPlOI1qSJ7hVMmmRM+wZjOoUgxqEPY2IMJ0/on1OLFlbmzj1pWLs+9flWK+EXX0xcs2Y+mL/CAPbvh2eegS1b9PKXX8Ltt/vUJG9jOoUgRpnlzIbicArnn28NlvCyxwTdcFSLBd5/H956S4eN6teHyZPhiit8bZnXCbJP0sQVI+WyTSDruP45NWnim9i+r1BKBVfRWnq6Hkm0a5deHjYMHngA6tTxrV0GYTqFIMZ0CsZyMlNr8Zx3Xuhcd2XTRWtBlbey2WDPHp07mDIF+vTxtUWGYjqFIMZ0Csbi6Cmcf37o9BSUshEZ6efCdJ6wdy+0aqUrkNu1g5de0npFASBgV9MEkXs3KYuZUzAWR07hvPNCxynYVADOfuZKfr4uQrvpJli16sz6P/0pJB0CmD2FoMbsKRiHzQYnMyOICYMmTULnuitlC9wahf/9D/7xDzh6VI/tPXzY1xb5BaZTCGIsFouvTQgZTp4Mw1Ii1GmkiI0NrR5awI08ys6Gf/0LvvhCL3fooBPLiYm+tctPCLBP06QqWK1mNbNRHD2qI7GhFDpyEFBOYfduPdlNVpauTr77brj1Vt1TMAFMpxDUWCwWxEwbGcLRo/qmEmrDUYHAGo7aooXOFVx4IUyb5tdzJfsK0ykEMTabDcyOgiH88Ye+MYbUcFT7QAa/dgpKwX//C5ddBrVrQ0wMzJsHDRsGjYBdTWNelSDGYrGYMhcG4QgfhdJwVJvNRnhYmP+GKA8f1qGiadPg1VfPrG/c2HQIlWD2FIIYq9WKmF0FQ3CEj0Ipp2C1Won2x16CzQYffwyvvaZnIKpTR893YOIRplMIYqxWa0BOBxiIaKegQq6nEBbuZ7eQ33+HZ5+FrVv18lVXwd/+prWLTDzCzz5Rk5rCUaNg+gTvY7FAZmYYiJXGjX2XU7DZbBQWFhrWnsVioU64H4VhDh+G//s/KCnROYPJk2HAAF9bFXCYTiFIMQvXjOPYsTBsNkioa8WXig9FRUUkJCRQy8BKXIs/SVw0bQoDB+qhpg88APHxvrYoIPGqUxCRQcArQDgwXyk1s8z2FsC/gbr2fSYrpZZ706ZQwZS4MA7HyKP6jUp8aodSijp16hgqO5EjPuwpFBVpaevLL4fOnfW6v//dTCJXE69dPREJB+YAfwY6AaNFpFOZ3aYCHymlegA3A697y55Qw+wpGMeRI9op1Gvouwpym81GeHh44EpOVJVNm2D0aD0T2j/+cWZeUtMhVBtv9hR6A3uUUnsBRCQVGA786rKPAhwi5QmAKT5SQ5hOwTj++EPfiHzpFIqKiqhbt67/Dg+tKfLy9Kiijz/Wy61bw+OPm86gBvGmU2gGHHRZPgRcXGafp4GvRGQiUBsY6O5AIjIeGA/QohoViGsz1mKxhYYeUGFhISdPniRMQi+uWvLzzzr7axCHN3ZB5Tamec6vlPxg3DScrkQc2UJYXC1yIoyN8UukgT2Tdevguefgjz+0LMW4cfCXv+gcgkmN4U2n4O6RpWygezSwQCn1LxHpC7wvIl2UUqUec5VS84B5AMnJyeccLLfYLAy4YMC5vj2gyM3N5agc5XRe6AyRdGKxEHnJJYY1d2xRXSQugpjerYi8pKNh7Tqw2WxEpOdQ97Lbg7enkJsLU6dCTg506qQL0tq187VVQYk3ncIh4AKX5eaUDw/dAQwCUEr9T0RigIbAMS/aFRJYrSHoDOwUFoWxY3MkRkXQDh/2bU6huLiY+NjY4HMISulXWBjExel6g8xMPezUH4vmggRvOoX1QDsRaQVkoBPJ/1dmnwPAlcACEekIxADHvWhTyGCxWOxTJIaec5j9SSfWpicY2mZkJMQn+OZa22w2YmJjfdK21zh+HGbO1LOf3XqrXjd4sG9tChG85hSUUhYRuQ/4Ej3c9B2l1A4ReQbYoJRaBjwMvCUiD6JDS7crcyxljRDKstnb9tYFoGvXEsMeKPv2LfJJrtNmsyEiRAaSfHVlKAXLlsGsWTpktG0b3HgjBPLsbgGGV79J9pqD5WXWPeny/6/An7xpQ6gSqk4hKyuMUzlRxJ2n+Oc/Txta0b12r/6bnZ1t6BwDdevWJSwzCEbfZGTA9Omwfr1evvRSeOIJ0yEYTJA8XpiUxWq12sNHocWePfor3bq1bxRibTYb0dHRtGzZ0rA2RQQyDWuu5rHZIDUV5szRBWl16+r8wdVXmzotPsB0CkGKxWLxb517L6Gdgo02bXyT9FVKER4eHpK9tGrxzTfaIVxzDTzyCNSr52uLQhbTKQQpVquVSH/SpTGI9PQIoJi2bX3jFGw2W0he9ypTUgL5+ZCQoEcXPfkkHDigJ8Mx8SmhF18IAZRSzgRkqOEIH/nSKYRiD61K/PorjBmjaw0c40patjQdgp9g9hSCkFB1CNnZwrFjYURF2rjgAt8MD1VKBdZE9kZSWAhvvgkLF+o8QmEhnDxpznXgZ5jf3iAkVHWPdOgIWjXJJSzMN9IHNpvNdAru2LhRjyw6eFCHi8aMgbvv1nMmm/gV5rfXIIy8UYdqNbMjdNSmWQ7QwCc2OBLNJnaUghdegI8+0stt2+r8Qaeygskm/oLpFAxAKcXBgwcpKfGt3n6wc8YpZOMrpwCE5FDgChHREhUREXDHHXD77fh0JiKTs2I6BQOw2WyUlJQYOiNWKLJ3r90pNM3xmQ0iYjqFU6fg0CHo0kUv33knDBqkZa5N/B6Pvr0iEiUibb1tTLBiMVDGOVQpKBAyMsIJD4cW5+X51JaQdQpKwVdfwQ03wMMPQ3a2Xh8VZTqEAOKs314RuRbYBnxtX04SkSXeNiyYsFgs5vSYXiY9PRyloGVLC5ERvr3WIekUjh3TjuCJJ3RPoXVrPbrIJODwJHz0DHpynNUASqnNZq+hahQXF4fkEFEjcYw88lUlswOlVGg5BZsNPvsMXnlFz4pWuzY8+CAMH25KVAQonjiFEqXUqTI3NfOxtwoUFxeH3IiUwkL49tsYcnKMuTH88IMWTfNV0RqAQoVeTuHZZ+E//9H/X3YZTJ4MjRv71iaTauGJU9gpIjcBYfa5Ee4HfvSuWcFFqDkFmw2ee64O69cbXyvQvr0FThjeLBCiw1H//Gc9TeYjj8BVV5m9gyDAE6dwH/AkYAM+Rc+P8Lg3jQomlFIUFRWRnWFD2YzvYIWFG/8jTU2txfr1UcTFKa66qtCw+0STJlbatbNg8ZFTOP/E/4gLi4bi34xvPMygYZ7p6fDzzzB6tF7u3RuWLoVgm+QnhPHEKVyjlHoMeMyxQkRGoh2EyVlwFJIpm6JJ+3gfW+N9NmyI5IMPaiECjz6aTa9eoVObIdYSSloNhqZNfW1KzVNcDAsWwDvvgMWii8+6d9fbTIcQVHjiFKZS3gFMcbPOxA2+rC5WCr7+Oppjx4wJaehJs2JRCm69NT+kHALo8w9KiYvt2+GZZ2CvfRahG27QlckmQUmF32ARuQYYBDQTkZdcNtVBh5JMPMCXw1HT0yOYNcv43kmvXsWMHp1veLu+RhFkukcFBTB3LqSkaI/XogVMnQo9e/raMhMvUtk3+BiwHSgEdriszwEme9OoYMKXw1GPHtWjYFq0sNKvX5EhbcbH27j6at/MV+xzgq2n8Prr2iG4CtiZU2MGPRV+g5VSm4BNIrJQKWVWoZwjZ0YeGR9GysrSd+YuXUq49dbQe3L3BUE1+mjcONizByZONAXsQghPnueaiUiqiGwVkd2Ol9ctCxKKiop8dqNwOIX69c1on1EEdI3Cd9/BpEk6kQx6Ssy5c02HEGJ48g1eALwLCPBn4CMg1Ys2BQ1KKZ/WKJw8aToFowlIp5CVpeUpHnoIfvgBPv/c1xaZ+BBPvsG1lFJfAiil0pVSU4HLvWtWcOAYeeSrnILZUzCegHIKSsHy5Xo00Vdf6QlvHnkEhg3ztWUmPsSTrFiR6Ltauoj8FcgAzDp2D/D1ZDcOp1CvnukUjCJgnMLRo/Dcc7pnALoIberU4KyxMKkSnjiFB4E4YBLwDyABGOdNo4IFX6ujmj0F4wkYp/Djj9ohxMdrAbuhQ02JChPAA6eglPrJ/m8OMAZARJp706hgwZfDUa1WOH06DBGzp2AESikQ34UKPaKg4Ez18fDhWu565Eho2NC3dpn4FZU+1ohILxG5TkQa2pc7i8h7mIJ4HlFUVOSzceunToWhFCQk2AimUZL+is1m899egtUK770HQ4ZARoZeJwLjx5sOwaQcFX6LRWQGsBC4BfiviExBz6mwBUg0xrzApri42Gc3CjN0ZCxKKUT80Cns3g233QazZ8Pp07Bmja8tMvFzKnuMHQ50V0oViEh94LB9eZcxpnmXvLw8cnNzvdpGUVGRz+ZlNp2CsfhdT6G4GN5+W4vYWa1w/vkwZQr07etry0z8nMqcQqFSqgBAKZUlIr8Fi0MAKCgo4PTp00RGek9yOCoqyhyOahBWq5Xc3FysViuqVSskK8vQ9pVSxF2QxM6dOw1t1y0lJXpKzPbtYcYMqFVLJ5TDwsAf7DPxKjExMTRv3vyc722VOYXWIuJQQhWgpcsySqmRZzu4iAwCXgHCgflKqZlu9rkJeBo9m9sWpdT/eW7+uWOz2YiMjCQ6SLVcQm04am5uLvXq1aNevXqQl4fExRnavs1mw1KYS1xdP4jRFxVpRdPISD3E1Ee9VRPjUUqRmZnJoUOHaNWq1TkdozKncH2Z5deqcmARCQfmAFcBh4D1IrJMKfWryz7t0BP2/EkpdVJEDKt/0DFgPx4pUk1CzSlYrVbq1auHiPhsrliffpsKCnTxmYgWrWvRQo808qeQlonXEREaNGjA8ePHz/kYlQnirTzno2p6A3uUUnsBRCQVnaf41WWfu4A5SqmT9jaPVbNNj/Fl/YARhKLEhc+dvC+at1rhjz90uKhZM0hI0Otr1/aBMSb+QHV/B94cL9kMOOiyfAi4uMw+iQAisg4dYnpaKfXfsgcSkfHAeIAWLVrUiHE2W3DfLB09hTqHt1Lyg7HxdV+gWrVC2QcOFFoV1iJjq8mVUsQa7RWys3VlssWiewg+rqA3CQ686RTc/ULKPp5HAO2AAUBz4HsR6aKUOlXqTUrNA+YBJCcn19gjvs+fLL2IM9FcK5/ISy7xsTXeR7KynHkEa5GVuGhjizNsNhu1azema9euWCwWWrVqxfvvv0/dunUB2LFjBxMnTuTQoUMopRg7dixTp051fgdXrFjBtGnTyMvLQynFkCFDePHFF0u1UVRUxLXXXsuJ48d5/O67GTVggN5QqxY0aeKc62DAgAG8+OKLJCcnl3r/ggUL2LBhA6+9VjoSrJTi/vvvZ/ny5dSqVYsFCxbQ081EOgUFBQwaNIhVq1Y5RR5nzZrF448/zh9//EGCvZfirh1Xm3Jzc3n44Yf55ptviImJoUGDBrzwwgtcfHHZZ0bP8eQccnJy6Nevn3P50KFD3Hrrrbz88svOdYsXL+bGG29k/fr1JCcns23bNv71r3+xYMGCc7Yt0PA44CgiVc3IHgIucFlujh7WWnafpUqpEqXU78AutJPwOjabLWidglJnwkf16hT72JrQITY2ls2bN7N9+3bq16/PnDlzAH0zHTZsGJMnT2b37t1s2bKFH374gddffx2A7du3c9999/HBBx+wc+dOtm/fTuvWrcsdf9OmTZQUFbH5o4+0QwgL00NNL7ywWpPfrFixgrS0NNLS0pg3bx733HOP2/3eeecdRo4cWUr1NyUlhV69erFkyRKP27vzzjupX78+aWlp7NixgwULFnDixIlztt/Tc4iPj2fz5s3O14XzIJsfAAAgAElEQVQXXsjIkWfGy+Tk5DB79uxSzqlr164cOnSIAwcOVMu+QOKsTkFEeovINiDNvtxdRF714NjrgXYi0kpEooCbgWVl9vkMu+KqvWo6EdhbBfvPmWDOKeTkCBYL1K6tiI4M7jCZv9K3b18y7NXDH374IX/605+4+uqrAahVqxavvfYaM2fqwXjPP/88U6ZMoUOHDoCeve3ee+8tdbxjx45x6623snnrVpKuu470zExW7ttHjyuvpGu3bowbN46iovKz67377rskJibSv39/1q1b59bWpUuXMnbsWESEPn36cOrUKY4cOVJuv4ULFzJ8+HDncnp6Orm5uUyfPp2UlBSPrkt6ejo//fQT06dPd9Z1tG7dmmuvvdaj91eEp+fgIC0tjWPHjpXqOUybNo1HH32UmJiYUvsOHTqU1NTQmS3Ak/DRbGAI+gaOUmqLiJxVOlspZRGR+4Av0fmCd5RSO0TkGWCDUmqZfdvVIvIremqyvymlMs/xXKpEMDuFUBt55I5Vv5376IuKuKJDI4/2s1qtrFy5kjvuuAPQoaOLLrqo1D5t2rQhNzeX7Oxstm/fzsMPP+z+YErBqVM0btCA+fPn8+KLL/L5Z59RWFLCgMREVq5cSWJiImPHjmXu3Lk88MADzrceOXKEp556io0bN5KQkMDll19Ojx49yjWRkZHBBRec6dQ3b96cjIwMmjRp4lxXXFzM3r17admypXNdSkoKo0ePpl+/fuzatYtjx47RuHHlAwh37NhBUlKSR3OMjBo1il27ypdGPfTQQ4wdO7bK5+BKSkoKo0aNckYLNm3axMGDB92G7ZKTk5k5cyaPPvroWW0OBjxxCmFKqf1lQi0eZbSUUsuB5WXWPenyvwIesr8MRSnlXxWoNYjpFGBAYoMaP2ZlgxPCwsIoKCggKSmJffv2cdFFF3HVVVcBlQ9/rjSEWVQER45Afr4ecuogIoJdO3bQqlUrEhO14sxtt93GnDlzSjmFn376iQEDBtCokXZmo0aNYvfu8pMmuntAKmvXiRMnnPkRB6mpqSxZsoSwsDBGjhzJxx9/zIQJE87tXN2waNEij/f15BxcSU1N5f333wf05/rggw9WmDdo3Lgxhw+XjXwHL544hYMi0htQ9tqDiUDAT8cZzHUKoTgc1R1GV5Q7cgqnT59myJAhzJkzh0mTJtG5c2e+++67Uvvu3buXuLg44uPj6dy5Mxs3bqR79+56o1KQmQnHj+v/IyKgTDGepz1dT86/efPmHDx4ZqDgoUOHaFpmXoXY2FgKC89M1b5161bS0tKcjq+4uJjWrVszYcIEGjRowMmTJ0u9Pysri4YNG1K3bl22bNnikSxIVXoKnpyDgy1btmCxWJy9t5ycHLZv384Ae+L+6NGjDBs2jGXLlpGcnExhYSGxDnXZEMCTR+V70E/yLYA/gD72dQFNKISPQt0piIihLwcJCQnMnj2bF198kZKSEm655RbWrl3LN998A+jE86RJk5zhiL/97W8899xz+im+sBBbejovPf+8dgh160KbNlCnTqlz69ChA/v27WPPnj0AvP/++/Tv37/UPhdffDFr1qwhMzOTkpISPv74Y7fXadiwYbz33nsopfjxxx9JSEgoF3apV68eVqvV6RhSUlJ4+umn2bdvH/v27ePw4cNkZGSwf/9+evXqxbp16zh69CgAGzZsoKioiAsuuIA2bdqQnJzMU0895fwNpqWlsXTp0nJ2LVq0qFRi2PEq6xA8PQcHjrCX6+d14sQJ57n06dPH6RAAdu/eTZcuXdweKxjxpKdgUUrd7HVLDCaY6xRMp0C5G7XR9OjRg+7du5OamsqYMWNYunQpEydOZMKECVitVsaMGcN9990HQLdu3Xj55ZcZffPN5J8+jQDXXn65rkquQK4jJiaGd999lxtvvBGLxUKvXr3461//WmqfJk2a8PTTT9O3b1+aNGlCz5493c4GOHjwYJYvX07btm2pVasW7777rts2r776atauXcvAgQNJTU1lxYoVpbaPGDGC1NRUHnvsMV555RUGDx6MzWYjLi6OlJQUZ89g/vz5PPzww872HENSq0Nl55CUlMTmzZudyx999BHLly93dxi3rF69utqJ8EBCzvbELCLp6KGii4BPlVI5RhhWEcnJyWrDhg3n9N41B9cw4IIBgB4FERMTY9iN48iuHJq0jzekrRkz4vnuu2j+9rcc+sWsDok6haysLGd8PafIQnx0BFFRUcYaUXgaYhKqd4zDh/VQ00aN8LeJMDZt2sRLL73kjMWHAkVFRfTv35+1a9f6bG6Uc2Hnzp107Nix1DoR2aiUSq7gLU7OGj5SSrUBpgMXAdtE5DMRCfieg5lTCGJUgBQmWq26Ijk//8y6Jk107YGfOQTQvZ/LL7/c53OPG8mBAweYOXNmQDmE6uLR8Bul1A9KqUlATyAbPflOwKKUMnMKQY7fO4XcXK1kmpWlHYPj++jndo8bN86j4aTBQrt27ZwJ6FDBk+K1OBG5RUT+A/wMHAcCOh4RzL0EMIekgh87BatVT4l54ICe9yAmRstb+6u9JiGHJ32i7cB/gOeVUt972R6TalJQIBQUCJGREBensPjaIB/hl06hrIBdo0bQoIHpEEz8Ck+cQmulVFA9cgZz+CgrS99g6te3mfcaf8Jq1YVoVms5ATsTE3+iQqcgIv9SSj0MfCIi5e6gnsy85s8Y+ST5xhu1WfN1HaLjvJ+sKinRf0M5n6Dwk56Ca54gPFwnkK1WqFfP7B2Y+C2V5RQcNeavoWdQK/sKWIzsJVitsGxZLCeyIjh2LMzrL8fIo86dSww7R39D8I1TCK9dn6SkJLp06cLQa6/l1LZtujIZrflzxYgRJPbpQ7vERJ599tlS38MVK1aQnJxMx44d6dChA4888ki54xcVFTFw4ECSkpIqlYAYMGAA7oZtL1iwwFkb4cpvv/1G3759iY6OLqf744pSiiuuuILs7GznuiVLliAi/Pbbb851a9asYciQIaXee/vtt7N48WIASkpKmDx5Mu3ataNLly707t27XM3DuTBjxgzatm1L+/bt+fLLLys8hylTppCYmEjHjh2ZPXs2UPE1KC4u5rLLLsNiCZ1AbGUzr/1s/7ejUqqUALtd6K66M7P5DCOdwsmTYSgF8XFW5r516uxvqAEiIqBBg9DsKfhyEEFsbCybN22Ckye5bdw45rz9NlPuu4+C2FiGDRvG3Llzufrqq8nPz+f666/n9ddfZ8KECU7p7C+++IIOHTpgsViYN29eueNv2rSJkpKSUoVYNUH9+vWZPXs2n332WaX7LV++nO7du1PHpbo6JSWFSy+9lNTUVJ5++mmP2ps2bRpHjhxh+/btREdH88cff/Dtt99W5xT49ddfSU1NZceOHRw+fJiBAweye/fuciOlFixYwMGDB/ntt98ICwvj2DE92WNF1yAqKoorr7ySRYsWccstt1TLxkDBkyGp49ysu6OmDQlWnPMa1LVy/vk2Q14NG4Z4PsFnJ69g/344epS+3buTcfIktGrFh6mpNSedvXkzSUlJpKens3LlSnr06EHXrl2rJZ3duHFjevXqRWRkZKVnV1Y6Ozc3l3Xr1vH22297LC2dn5/PW2+9xauvvkq0Pady3nnncdNNN3n0/opYunQpN998M9HR0bRq1Yq2bdvy888/l9tv7ty5PPnkk87qaoeqa2XX4LrrrmPhwoAehV8lKsspjELPgdBKRD512RQPGPPI6yWM7Ck4hofWTQidgh9fonsKwK7qhyPK0f7PFTWqw0Q2Bfn5WEVYuXUrd9x9N0REVE86207jxo3PSGd//jmFhYUMGDCgRqSzPWXdunW8+eabzuXPPvuMQYMGkZiYSP369fnll1/cztjmyp49e2jRokWp3kZFPPjgg6xevbrc+ptvvpnJkyeXWpeRkUGfPn2cyw7p7LKkp6ezaNEilixZQqNGjZg9ezbt2lU+r1eXLl1Yv379We0NFirLfP4MZKJnTHPNIeQAm7xplLfxhVOoYzlGyQ/bDGvXwW+ZxZzee9rwdo2mdW0buUVWbEoRqwrgQi+U0hRWcB2VgtNZFBQVkXTjjezLyKgZ6exK2LVrV41JZ3tKVlYW8fFnpFpSUlKc7d18882kpKTQs2fPGjvXWbNmebyvp9LZRUVFxMTEsGHDBj799FPGjRvH999XPtI+PDycqKgocnJySp1/sFJZTuF34HfgG+PMCT6cPYVahT7RIDq99zSXtq6mHk8AkJWVRVx0ODabjShbePU1iM6GzaZfDvmD5rE6p7BjR/Wlsz2gJqWzPSUiIsIpeZ2ZmcmqVavYvn07IoLVakVEeP755yuVzm7bti0HDhzw6AZblZ6Cp9LZzZs35/rrrwe0gN9f/vIXj87d4UxCgQpzCiLyrf3vSRHJcnmdFJEs40yseXwSPooz50o2DG+nFPLytERFRsaZYacuNQfVks5GK/i+9NJLlZpQk9LZntK+fXv27tWz5S5evJixY8eyf/9+9u3bx8GDB2nVqhVr166lXbt2HD58mJ07dwKwf/9+tmzZQlJSErVq1eKOO+5g0qRJFBfr38SRI0f44IMPyrU3a9Yst9LZZR0CaOns1NRUioqK+P3330lLS6N3797l9rvuuutYtWoVAN9++62zp1UZmZmZNGrU6Kw5l2ChsvCRY8rNhkYYYiSmUwhuvOYTrFY4dgwcT8Eiep0bsbRzks4ePZr8/HxE5KxSzTUpnX306FGSk5PJzs4mLCyMl19+mV9//bVc3P/aa69lzZo1tG3blpSUlHI35+uvv54PP/yQfv368cEHH/CXv/yFwsJCIiMjmT9/PgkJuvc2ffp0pk6dSqdOnYiJiaF27do888wzlV/7s9C5c2duuukmOnXqREREBHPmzHGOPBo8eDDz58+nadOmTJ48mVtuuYVZs2YRFxfH/Pnzz3oNVq9ezeDBg6tlXyDhiXR2S+CwUqpYRC4FugEfKKWyK32jl6gJ6eyCggIyMjKoVatWDVtXnvvvr8vu3RE8OmQdl09o7/X2yrI2hMJHiYmJ2Gw2olURElvD55ybqyuSS0q0M2jYUEtUBOmUru44cuQIY8eO5euvv/a1KYYycuRIZsyYQfv2xv9+zxWvSmcDn6Gn4mwDvAd0BD48F0P9BSNlLsyegrHoyXVq8IBK6TkOHAJ2sbHQqpXWLQohhwC653HXXXeVKl4LdoqLi7nuuusCyiFUF090F2xKqRIRGQm8rJSaLSIBPfoIjKl4VepMnUJCbdMpeBvnKJ+a9PciEBmp/zZuDPXrh7RERXXrCQKNqKgot9N/BjMeTccpIjcCY4Dr7OsCOuNiVE8hO1uwWqF2bUVUZGhWGBtNWFgYVPdSl5TolyO82KABJCSA0TO5mZj4AE8rmi9HS2fvFZFWQIp3zfIuRkkhOKuZQ3heAyOp9ueqFJw6pUcWHTqkJa5Bh4lMh2ASIpy1p6CU2i4ik4C2ItIB2KOU+of3TQt8zBnQAojiYp1IzsvTyyFQpGRi4o6zOgUR6Qe8D2SgR/udLyJjlFLuhVQCAKPCR6HuFKxWq1s9Hm9gs+lrXOWeglJ6Sszjx3UxmkPiuk6dkM4dmIQunoSPZgGDlVJ/UkpdAlwLvOJds7yLzWYzJHwU6k6hqKiIunXr0rBhQ6+/wsPDiYiIqPrnevgw/PGHdggJCdCmjf57Dt+P8PDwM9LZQ4dy6tQZibAdO3ZwxRVXkJiYSLt27fxKOnvhwoV069aNbt26cckll7Blyxa3xw0G6exVq1bRs2dPunTpwm233VZKEnvNmjUkJSXRuXNnZyGgKZ3tniil1K+OBaXUThExA6weEMpOwXHDq1+/vlOR0pscOXKECDdFZGelbl3Iz9e9g2qGjGJjY52y1g4toilTplBQUODX0tmtWrXi22+/pV69eqxYsYLx48fz008/ldsv0KWzbTYbt912m1NE8Mknn+Tf//43d9xxB6dOneLee+/lv//9Ly1atHBKapvS2e75RUTeFJFL7a+5BLggnlE9BUeiORSdQlFREfHx8YY4hCpRUAAnTpxZrl1b9w5qOIfQt29fp0rnhx9+6NfS2Zdccgn16tUDoE+fPhw6dMjtfoEunZ2ZmUl0dLRT2uKqq67ik08+AfRnNHLkSFq0aAGckdQGUzrbHX8FJgGPonMK3wGvetMob+OIP3ubUj2F0Kn3AXQ+wZeKkmsOrim9wmaD7GzIydHLpxpXeY7kARcM8Gg/q9XKypUrueMOPe1IIElnv/322/z5z+4lwgNdOrthw4aUlJSwYcMGkpOTWbx4sVNEb/fu3ZSUlDBgwABycnK4//77nfUJpnS2CyLSFWgDLFFKPW+MScZgeE5hn9eb8xscSpq+VJUsdQPPy9Mji8KLoZ7oAjQvVCQXFBSQlJTEvn37AlI6e/Xq1bz99tusXbvW7fZAl84WEVJTU3nwwQcpKiri6quvdoYcLRYLGzduZOXKlRQUFNC3b1/69OlDYmKiKZ3tQESeQM+w9gvQS0SeUUq9Y5hlXsRoiYt69WyBPStRFSkuLvaP0FFZAbvoaGjaVEtVeAFHTiEQpbO3bt3KnXfeyYoVK2jQoIHbfYJBOrtv377O+RO++uorp5Ns3rw5DRs2pHbt2tSuXZvLLruMLVu2OJ2uKZ2tuQXoppS6EegF3FPVg4vIIBHZJSJ7RKS83u2Z/W4QESUiZxVrqgmMyCkUFAiFhUJkpK5oDiVsNpt/PFEdP64dgojuGbRq5TWH4EqgSWcfOHCAkSNH8v7771cqJR0M0tmOBHJRURH//Oc/ncqyw4cP5/vvv8disZCfn89PP/3kFJQLNensypxCkVIqD0Apdfws+5ZDRMLRM7b9GegEjBaRTm72i0fnLMoPd/ASRtcohNJwd4fDja5ivL7GcP1sGzbUCeTWrQ0XsHOVzo6NjWXp0qVMnz6d9u3b07VrV3r16uVWOrtjx4506dKFI0eOVHp8V+nsrl27EhYWVql09sCBAyuM9z/zzDNkZmZy7733kpSURHKy+2czh3Q26NDRiBEjSm13SGdHR0c7pbOTkpK44YYbyklnN2rUiE6dOtGlSxeuu+46Z4jrXHGVzh40aFA56ezDhw8D8MILL9CxY0e6devG0KFDueKKKwDo2LEjgwYNolu3bvTu3Zs777yTLl26AJjS2c4NIqeAVY5FtNSFYxml1MhKDyzSF3haKXWNfflx+/tmlNnvZfTsbo8AjyilKtXFrgnp7KNHj1JYWEiUF6ULtm2L5NFHE+jY0cJLL53i0NL1NB/ey2vtVcT3e0+R3MS4G7TFYqF+/frV/pFXlZ07d9KxaVMtU9E4AWLrGtp+KGBKZweOUmp1pLMrSzRfX2b5tSra1Qw46LJ8CLjYdQcR6QFcoJT6XETKV+uc2W88MB5wDhk7Fw6v+Im10SfJyc3BarUSHhZ+9jedI7/sbEL+yR5YThxly6e/kJdXi32+mCvZZiU6OpratWsb1mRcXJz+J+0bsJV4v8HMU2BtCjZ7gVFspOkUvICrdLYno4eCAVM62wWl1MpqHttd0MTZLRGRMHS19O1nO5BSah4wD3RP4VwNUhYbl44fweHDhykpKfFqjHDvklhqra1Nhz5RdB9ZnyO7cmjS2vg4e35+PvHx8c6uu6HYSqC9++GNNXN8G3z2Gbw8F55+GiKi4LzzdEWyiVcwpbODn3MoAfWYQ8AFLsvNgcMuy/FAF2CNPel7PrBMRIadLYRUXYyoUziTUyg//aGRKKWCM0F28CBMnw4bN+rlmBidOwjGczUxMRBvZt7WA+1EpJVdFuNmYJljo1LqtFKqoVKqpVKqJfAj4HWH4MDbo4/8ReJCRM5N/sHf2bRJO4T69WHmTKhXz3QIJiY1gMd3CxGJVkp5LHmplLKIyH3Al0A48I5SaoeIPANsUEotq/wI3sPI0Uf+MJdC0DiFnJwzchRDh+qk8vDhOlxkH/5oYmJSPc7aUxCR3iKyDUizL3cXEY9kLpRSy5VSiUqpNo45GJRST7pzCEqpAUb1EoyoU/CHnoLVaiUiIsL3RWTVpbgY3nwThgzRcyWDrj0YO9bMH5iY1DCe3C1mA0OATACl1Bb08NSAxWJR/PZbFNu2RXrtlZnpH04h4Kswt22DW2+Ft97SchU//uhriyokUKWzly5dSrdu3Zw1ChXJXBQUFNC/f3+s1jN5slmzZhETE8Pp02dG1rlrx9Wm3Nxc7r77btq0aUPnzp257LLL3KqyVgWlFJMmTaJt27Z069aNX375pdw+OTk5JCUlOV8NGzYsJQsCuihPRJy2btu2jdtvv71atgUansQVwpRS+8s8Wfs2e1pNFi6MY/HiOl4vKgsPh4QE31UzWywW3xWRVZeCApg7F1JSdEFaixYwbRqcRdDNlwSqdPaVV17JsGHDEBG2bt3KTTfdVGp+BAfvvPMOI0eOLCVHnZKSQq9evViyZInHN88777yTVq1akZaWRlhYGHv37nVWP58rK1asIC0tjbS0NH766Sfuueeeco4mPj6+1LW76KKLGDnyTLlVTk4Os2fP5uKLz4yc79q1K4cOHeLAgQPVGg4fSHjiFA6KSG9A2auUJwIVq2oFAIcO6dO+4AIrdet670m+d+9iI4to3eLNAj2vsX07TJkCGRm6CnnsWBg/vsqqpr6kb9++bN26FahYOnvAgAFMmDChStLZx48fJykpiU8++YR9+/bxyCOPYLFY6NWrF3Pnzi33EPDuu+8yY8YMmjRpQmJiotuHBGddCZCXl1dhaHXhwoV8+OGHzuX09HRyc3N54YUXeO655zxyCunp6fz0008sXLjQGdZs3bo1rVu3Put7K2Pp0qWMHTsWEaFPnz6cOnWKI0eO0KRJE7f7p6WlcezYMfr16+dcN23aNB599FFefPHFUvsOHTqU1NRUpyxJsOOJU7gHHUJqAfyBrj6usg6SP1FUpEPSd96ZR+/exb42x6sE5HDU+HitW5SYqHsHZSozPSFnVXkhtWqbdYVnUdNAlM5esmQJjz/+OMeOHeOLL74ot724uJi9e/fSsmVL57qUlBRGjx5Nv3792LVrF8eOHSs1D4E7duzYQVJSUqneRkWMGjWKXbt2lVv/0EMPlasdyMjI4IILzoyAd0hnV+QUUlJSGDVqlNMBbtq0iYMHDzJkyJByTiE5OZmZM2eaTsGBUuoYejhp0FBYqL8IMTHBLVSnlAqckUebN0P37tpbX3ghvPEGdOoE52i/pzfwmiSQpbNHjBjBiBEj+O6775g2bZpTvM/BiRMnqFu3dJV4amoqS5YsISwsjJEjR/Lxxx8zYcKEGjvXyvImZfFEOtuV1NRU3n//fUAPPHnwwQdZsGCB230bN27s1E4KBTwZffSWiMwr+zLCOG+glAoJp2Cz2QJj5FFWFjzxBNx5JyxffmZ9t27n7BB8hSOnsH//foqLi5kzZw6gxdrKJn7dSWdXhZqWznZw2WWXkZ6ezgnX2enQ51ZYWOhc3rp1K2lpaVx11VW0bNmS1NRUUlJSACqVzu7cuTNbtmzxqIB01KhRpRLDjtd7771Xbl9PpbMBtmzZgsVicfbecnJy2L59OwMGDKBly5b8+OOPDBs2zPmZFRYWEmuAuq6/4Mkd4xtgpf21DmgMeFyv4I8UFurTjo4OXqdgsVj8e+SRUtoJ3HADfPWVrkguMUAnyQACTTp7z549Tifzyy+/UFxcXG5OhXr16mG1Wp2OISUlhaeffpp9+/axb98+Dh8+TEZGBvv376dXr16sW7eOo0ePArBhwwaKioq44IILaNOmDcnJyTz11FPONtPS0li6dGk5uxYtWuRWOtud7MSwYcN47733UErx448/kpCQUGnoaPTo0c7lhIQETpw44TyXPn36sGzZMqda7O7du52KqaGAJ+GjUn04EXkfCFiZxFDpKfj1cNSjR+G55+CHH/TyxRfrxHIFT3aBiKt09pgxY1i6dCkTJ05kwoQJWK1WxowZ41Y6Oz8/HxHh2muvrfT4rtLZjkRzZdLZTZo0oWfPnqWGkzr45JNPeO+994iMjCQ2NpZFixa57WFcffXVrF27loEDB5KamsqKFStKbR8xYgSpqak89thjvPLKKwwePBibzUZcXBwpKSnOXuv8+fN5+OGHadu2LbVq1aJBgwa88MILVbq+ZRk8eDDLly93HvPdd991bktKSio16uijjz5iuWuv9CysXr36rJ9HMFGhdHaFbxBpA3yplGrrHZMqpzrS2Qtfn8HNdz/KpZcWkZ8fwaJFmdSpY4xjOLIrhybtjRPEy8vLo2nTpoaqo5Zj14rygnjbt8O990J+vk4oP/SQLkqr5vhgd1LBJjXLpk2beOmll5yx+FCgqKiI/v37s3bt2sDJz+E96WzHgU5yRt00DMgCKpxFLRBwhI+Cuafgt5pHiYlaybRlS3jsMT0RjklA0KNHDy6//HItO+/B6KFg4MCBA8ycOdM/f0teotIzFd2H7A5k2FfZlFETHHsJi0VhsegcZiCO1qwKfvFFtlph0SLdG6hTB6Ki4O239f8mAce4ceN8bYKhtGvXjnbt2vnaDEOpNNFsdwBLlFJW+yugHQJAfr4+hehoFbTTZNpsNsLDw33/NPf7IbjtNnjpJf1yYDoEExO/xZNHyZ9FpKdSqryYSABSUKD/Gh06KiouIj/fmJu0zWYjPt74CX2cFBfD/Pnw5isQGQ/nnw/XXOM7e0xMTDymQqcgIhFKKQtwKXCXiKQDeegZ1ZRSyv0s4H6Oo6dgpFNwdLCaNWtmWJs+Cx1t3QrPPAP79oFNwU03wX33Qa1avrHHxMSkSlR25/gZ6AlcZ5AthuCovzHaKYSFhfumAMaoeZIBjhyHSf/Q02Q2bQz3PQzD7jambRMTkxqhspyCACil0t29DLKvxjkTPjKuTZvNRrivKosd8yQb8RowFkbfDvc+CJ+vDjmHEKjS2Q7Wr0oAquwAACAASURBVF9PeHg4ixcvdrs90KWzQReude3alW7dujFo0CBn5bZr9XTLli1JSkoCQlM6u7I7VSMReaiil2EW1jB5eWcSzUahewp+LjdxLmRn61DRpk1n1k2erOsQAlGdtZo4ZC62b99O/fr1nTIXDunsyZMns3v3brZs2cIPP/zA66+/DuCUzv7ggw/YuXMn27dvd6sa6iqdPWrUqBq13Wq18thjj3FNJbmfs0lne8qdd95J/fr1SUtLY8eOHSxYsKCcrEZVcZXOnjdvHvfcU16z02KxcP/997N69Wq2bt1Kt27deO2114DS1dPXX3+9U1LbVTo7VKjsThUOxAHxFbwCEl9UM9tsNsJ8PRKoplm1Cm68EZYtg+ef17IVUO0itGChb9++ZGTokdwVSWfPnDkToErS2Zs3byYpKYn09HRWrlxJjx496Nq1K+PGjaOoqLz6zLvvvktiYiL9+/dn3bp1Fdr76quvcv3111eqcrpw4UKGDx/uXHZIZ0+fPt2pe3Q2HNLZ06dPLyWdXd2K4Yqks11RSqGUIi8vD6UU2dnZ5fSRlFJ89NFHpWQwHNLZoUJlOYUjSqlnDLPEIAoKfJNo9ln4qKbJzIR//lM7BYCkJC1v7WfO4Pet1XvydEerbp4V2gWadHZGRgZLlixh1apVrF+/3m37wSCdHRkZydy5c+natSu1a9emXbt2zt6cg++//57zzjuvVG2CKZ19Bv/6ldcQvhiSqusGArxSTin44gtdb5CdrUcTTZwI11+Pz2cScoOnN/CaJFClsx944AH++c9/VnqjDgbp7JKSEubOncumTZto3bo1EydOZMaMGUydOtW5T1mxPAg96ezKnMKVhllhIL6qUwj4nEJODsyapR3CJZfA449DBSqUoYojp3D69GmGDBnCnDlzmDRpEp07d+a7774rta876ezu3bt73FZNSmdv2LCBm2/WU6acOHGC5cuXExERwXXXnRl4WJl0NuieROvWrZkwYUKl0tl169Z1Smef7TdRlZ6CJ9LZDlG8Nm3aAHDTTTc5Q3igcw6ffvppORlzUzrbjlIqy0hDjMLhFIyWzZZAdAo2m5apAF2FPGWKTiy/8orpECoh0KSzf//9d6ds9A033MDrr79eyiFAcEhnN2vWjF9//ZXjx48D8PXXX5cSjfvmm2/o0KEDzZs3L/W+UJPODsA7VfVwOIXYWIOdgqGt1QD79sFdd4HrbFRXXAGDB/td/sAfcZXOjo2NZenSpUyfPp327dvTtWtXevXq5VY6u2PHjnTp0qVckrQsrtLZXbt2JSwsrFLp7IEDB9KzZ/XqTR3S2aBDRyNGjCi13SGdfd555zmls5OSknjggQfKSWcfPXqUtm3b0rVrV+66664KJ8TxlMGDB9O6dWvatm3LXXfd5RzZBTiHlzZt2pSnnnqKyy67jG7durF582aeeOIJ536pqanlQkdgSmf7PdWVzt6b+RAffaS49958hg8vPPubaoD8/Hxsp2uTeJEPnq7dyVdXhsUC770Hb72lJ71p2hQWL/b7IaamdLb3MaWz/UBg0kO8Kp0dbPiieA0gLBCernftgr//HRzJyOHD4f77/d4hmBiDKZ0dGoTOmdrx1ZDUsDA/dgoWC7z5Jvz733aJiqYwdSr07u1ry0z8DFM6O/gJQacggDI80Rwmfpy+CQ/XM6IpBaNHwz33mAJ2JiYhSgg6Bf3XqESzU+LC38JH+fmQlweNGmnbpk2DEyegWzdfW2ZiYuJD/Pjx1TsYrZJqs9n8Lx75v/9pSeupU8/IUzRtajoEExOT0OspaKcghjkFpRTh4eHYDGntLJw+rSuSv/hCL9erp9eVqVQ1MTEJXbzaUxCRQSKyS0T2iMhkN9sfEpFfRWSriKwUkQu9aQ84cgrGFa85psb0KUrBypVawO6LL/RookmTdA2C6RBqlKNHj3LzzTfTpk0bOnXqxODBg5k3bx5DhgzxtWkmJh7htZ6CiIQDc4CrgEPAehFZppT61WW3TUCyUipfRO4BngdqVhO4DEaHj5RSvg0fKaXDRF9+qZd79tTLLVr4zqYgRSnFiBEjuO2225yqmps3b+Y///mPjy0zMfEcb/YUegN7lFJ7lVLFQCow3HUHpdRqpVS+ffFHoDlextFTCJmcggi0bq1HEz3+OLzxRmg4hOTkil+ffnpmv08/rXzfKrB69WoiIyNLVRYnJSXRr18/cnNzueGGG+jQoQO33HKLU+LhmWeeoVevXnTp0oXx48c71w8YMIDHHnuM3r17k5iYyPfffw9oBdZHHnnEOVHMq6++CsDGjRvp378/F110Eddcc81ZK6JNTCrCm3erZsBBl+VDwMWV7H8HsMLdBhEZD4wHaFGNG1rM6QNYcrMJR1Hn6GpjBgQVFRF1ug4cjYdogzILf2TCHyegW3sIi4TbboOhQ+EsssYm1WP79u3lJLIdbNq0iR07dtC0aVP+9Kc/sW7dOi699FLuu+8+nnzySQDGjBnD559/ztChQwEt0Pbzzz+zfPly/v73v/PNN98wb948fv/9dzZt2kRERARZWVmUlJQwceJEli5dSqNGjVi0aBFTpkzhnXfeMezcTYIHbzoFd7dct4/nInIrkAz0d7ddKTUPmAda5uJcDSq2RGCLiicqykZxy8vP9TBVIj8/nzrnn8//t3fm4VVV57//vIQMRGYEi8RAmFJIgAhq9IrI1AhokalCLogIiBS8xVr84XCrsRfBKhRNZagDlzIlSPpDqAJeRqtAlAAphgiiGE3ACjIJJCQkWfePvXM4mU/IOSck5/08z36es9dee693nZzsd6/1rv1+qX8Zwj2czrmwENasgYVLIDAQ1o6H5s2tY77mEFxNhTJihLV5mDvuuMORaK0ovXbv3r3ZsWMHr776KtnZ2Zw5c4aIiAiHUyhS/+rVqxcZGRmAlbRt6tSpjtFn8+bNSUtLIy0tzZGxtKCgoFQyOEVxFU86hSzgFqf9EKBUUnIRGQg8D9xrjCktHeVG8q5YmgbeTobnlbTZx47B7Nlw8KC136fPdalzUJeJiIgoV984MDDQ8dnPz4/8/HwuX77MtGnTSElJ4ZZbbiEuLq5Yeuqic4rqQ9naDMYYIiIi2LNnj7u7pPggnrxr7AU6iUiYiAQAY4ANzhVE5Fbgb8BQY8xJD9oCQN6VAIzxftpsjzqF/Hx4910YO9ZyCC1bWstO58zRlUVepn///uTm5vL22287yvbu3cvHH39cZv0iB3DjjTdy8eLFch2KMzExMSxZssThJM6cOUN4eDinTp1yOIUrV65w6NCh6nZH8VE8drcyxuQDTwAfAV8C7xljDonIn0RkqF3tNSwd6LUikioiG8q5nFsoGinUKYGd55+HxYutjKbDh8PatdYoQfE6IsK6devYsmULHTp0ICIigri4uHLTQjdt2pTHHnuMbt26MWzYMG6//fZK25g8eTKhoaF0796dHj16sHr1agICAkhKSmLWrFn06NGDqKgodu/e7e7uKT6CT6XOXvDkn/i/258hPDyPN9742c2WlU12djbt2rUjM/2cZyQiU1OtzKbPPQcu3FTqKpo6W1GuUp3U2T416WyNFIz302a7c6Swfz+89dbV/agoS+/Ahx2Coijuw6fSXORdsXQBvPniGly7OHsxLl2C+Hj4xz+s/dtus15EAyvLqaIoihvwLaeQ7+/VQHNR3qNqO4Vdu+Dll+HkSahfHyZOhG7d3GOkoiiKE77lFLw8Uqh23qNz52D+fNhkv9MXEQEvvAAdOrjHQEVRlBL4llPIrw8YGjTwTnvGGPz9/a/9Am+/bTmEwECYNs0SwNF3DxRF8SC+5RRqIKZQ5SCzMVcFeR5/HM6cgenTIcTjaaEURVF8cfWR995orlIyPGNg3TorXpCXZ5U1bgxz56pDUBTFa/jYSKHo5TXvtOdyTCEry0pRUfT+xZYtcP/9njVOURSlDHxypODNN5orHCkUFsKqVTB6tOUQmjWz0lMMGeI1+xT3IiI8/PDDjv38/HxatmzpcZEdPz8/oqKiiIyM5Ne//jXnzp1zHMvKyuLBBx+kU6dOdOjQgRkzZpBXNBqlbGGgr776qlQbOTk53HvvvRQUFDjK1q1bh4hw+PBhR1lGRgaRkZHFzo2Li2PevHlVaq+qbN68mfDwcDp27Mgrr7xS6viRI0eIiopybI0bN+b11193HF+wYAERERFERkYSGxtbLA+Vp2wCmDhxIq1atSr1nWVmZtKvXz+6dOlCREQEb7zxBgB5eXn06dPHkerE3fiWU8j3rlOoMKZw7Bg8+igsWAC5uTB4sJWiIiYG7+T0VjzBDTfcQFpaGjk5OQBs2bKFNm3aeLzdBg0akJqaSlpaGs2bN2fhwoWA9RscMWIEw4YN4+jRo3z11VdcvHiR559/3nF8+PDh9O3bl2+++Yb09HTmzJnDjz/+WKqNpUuXMmLEiGKj34SEBHr37u0QFaqMqrRXFQoKCpg+fTqbNm0iPT2dhIQE0tPTi9UJDw8nNTWV1NRU9u3bR3BwMMOHDwfg+PHjxMfHk5KSQlpaGgUFBRX2aefOnUyYMKHaNgFMmDCBzZs3lyqvX78+8+fP58svvyQ5OZmFCxeSnp5OQEAAAwYMYM2aNS58M1XHR6ePvOMURKR8p3D4MBw6ZKW0fu456N3bKzb5AlXUxnEZV7OrDB48mA8//JBRo0aRkJBAbGysQyRn5cqVxMfHk5eXR3R0NIsWLcLPz49hw4aRmZnJ5cuXmTFjBlOmTCEjI4PBgwfTu3dvdu/eTZs2bVi/fj0NKlk+d9ddd3HQzpa7fft2goKCePTRRwFrRLFgwQLCwsJ46aWXSE5OLlMYqCxWrVrF6tWrHfsXL15k165d7Nixg6FDhxIXF1fpd1OeEFF1+fzzz+nYsSPt27cHYMyYMaxfv56uXbuWWX/btm106NCBtm2vKgDn5+eTk5ODv78/2dnZ5eascrdNffr0caRGd6Z169aOFOiNGjWiS5cuHD9+nK5duzJs2DCeffZZxo4dWy0by8KnRgq59uojb2ZJLeYUzp69+nnwYPiv/4L33lOHUMcYM2YMiYmJXL58mYMHDxIdbWlLffnll6xZs4Zdu3aRmpqKn58fq1atAqyn8H379pGSkkJ8fDynT58G4OjRo0yfPp1Dhw7RtGlT/lH0Rns5FBQUsG3bNoYOtXJOHjp0qJTwT+PGjQkNDeXrr7+uUBjImby8PI4dO0a7du0cZe+//z6DBg2ic+fONG/enP3791d6HVfbA7jnnnuKTfcUbVu3bi1V9/jx49xyy9VM/SEhIRw/frzcaycmJhIbG+vYb9OmDTNnziQ0NJTWrVvTpEkTYmJiSp0XHR1NVFQUkydPZsOGDQ6bPiqSu62GTRWRkZHBgQMHHL+lyMhI9u7de03XqgwfGyl4d0kq2E7h8mUar1wCuzfDihUQFmZNET30kNfs8CWuMV+i2+jevTsZGRkkJCQwxCk+tG3bNvbt2+fIhpqTk0MrW/woPj6edevWAdZc8tGjR/nFL35BWFiY40naWWynJDk5OQ7xnl69ejkEd8rSX6iovDx++uknmpZIxZ6QkMCTTz4JWI4wISGBnj17lnvdqr7ZXzS6coWyEnuW115eXh4bNmxg7ty5jrKzZ8+yfv16vv32W5o2bcpvfvMbVq5cybhx44qd+9lnnwHW9NGyZctYtmyZW2yqiIsXLzJy5Ehef/11GjduDFgjvoCAAC5cuECjRo2qfM2K8DGn4P1Ac739+2HuXBoezYAbAuDAAcspKHWaoUOHMnPmTHbu3Ol46jfG8MgjjxS7GYF1g9m6dSt79uwhODiYvn37OoKcJcV5imIVJSmKKZw/f54HHniAhQsX8rvf/Y6IiIhSo4uff/6ZzMxMOnTowMmTJ13ScWjQoEGxwOvp06fZvn07aWlpiAgFBQWICK+++iotWrTgrPOoGEv3ISwsjJCQEJfaA2ukcOHChVLl8+bNY+DAgcXKQkJCyMy8qv6blZVV7vTPpk2b6NmzJzfddJOjbOvWrYSFhdGyZUvAUr3bvXt3KadQFapiU3lcuXKFkSNHMnbsWIcSXxG5ubkEeWAppU9NH3kz0CyXLtFs8WLqTZ8OWVlcuSUMli3zivSjUvNMnDiRF154gW5OOaoGDBhAUlISJ09aelJnzpzhu+++4/z58zRr1ozg4GAOHz5McnLyNbfbpEkT4uPjmTdvHleuXGHAgAFkZ2ezfPlywJpe+sMf/sCECRMIDg52WRioWbNmFBQUOBxDUlIS48eP57vvviMjI4PMzEzCwsL49NNPadiwIa1bt2bbtm2Ofm7evJnevXtXSYjok08+cQSGnbeSDgHg9ttv5+jRo3z77bfk5eWRmJjomEIrSVGcx5nQ0FCSk5PJzs7GGMO2bdsqTMXet2/fCkcJVbWpLIwxTJo0iS5duvDUU08VO3b69GlatmxZvYwJ5eBTTqFxa+sfNCjIkJOTQ3Z2tke2/JQUGj/2GA23bEHq14epUzn18iIoJ+il1D1CQkKYMWNGsbKuXbsye/ZsYmJi6N69O7/61a/44YcfGDRoEPn5+XTv3p0//vGP3HnnndVq+9Zbb6VHjx4kJiY6hH/Wrl1Lp06d6Ny5M0FBQcyZMweomjBQTEwMn376KWDdWItW7hQxcuRIRyB6+fLlzJ49m6ioKPr378+LL75Ihw4dqixE5Cr169fnzTff5L777qNLly489NBDREREADBkyBBOnLCUgLOzs9myZUupp+7o6GhGjRpFz5496datG4WFhUyZMqVUO0UxhZJbWTEFV22KjY3lrrvu4siRI4SEhPDuu+8CsGvXLlasWMH27dsd7WzcuBGwAvZDPLR03adEdu66q5CLF/N4//2zGHOJm2++2SOelsxM/MaOhc6dqffii9C+Pd8e/MkzIjsKoCI73uDAgQP85S9/YcWKFTVtis8zYsQI5s6dS3h4eJnHqyOy4zMxhcLCq9kjAgMNOTmGoKAg9wjgGAOffQbR0VYAuX17WLoUwsM1gZ1SZ7j11lvp168fBQUF1cv+q1SLvLw8hg0bVq5DqC4+c8cqipEFBBjAyknkFofw44/w+9/DE0/AP/95tbxLF3UISp1j4sSJ6hBqmICAAMaPH++x6/vMSOHyZeuBvkEDQ35+fvWj9oWF8P778PrrkJ0NDRuCJ6aiFEVRvIjPOAVrJZ8hMNBQUFBQPafw/fdWAruil3X69oVZs8BezqYoilJb8TGnAEFBhRQWFhIQEHBtFzp4EKZOtQIUzZtbbyUPGKD5ihRFqRP4nFMICLDe5HRZ56AkXbpAaKgVRH7qKWjSxH1GKoqi1DA+5xSKXlxz2Snk5cHKldZLZ02bWnGDpUshONhDliqKotQcPrM8pmj1UWCgJXzj0gqKL76AceNg0SKYP/9quToERVHqKD43UggIKCiWT6bcyosXQ0KCtWQpNFTTUyiK4hP4lFMwxgWn8Pnn1sqiEyes9wweeQSmTIFrDUwrNUJmZia5ubluu15gYGCxNMjuYOLEiXzwwQe0atWKtLQ0l887d+4cq1evZtq0aWUej4uLo2HDhsycOdOl61W1vlK38Znpo6tLUgvLX476/fcwfbrlEDp3huXLrZfS1CHUOnJzcwkODnbbVlUH44oyV3mKW5Vx7tw5Fi1aVOXzFMUVfMwpQIMGFQSZQ0MhNhamTbMcwi9/6T0DFZ+jT58+NG/evMI6ly5d4v7776dHjx5ERkayZs0annnmGb755huioqJ4+umnAXj55ZcJDw9n4MCBHDlypNK2K6q/cuVK7rjjDqKionj88ccpKChg1qxZxRxRXFwc853jbEqdwaemjwCCg52Wo545A6+9BiNHXtVwLJGiVlGqQnR0NLm5uVy8eJEzZ844BHL+/Oc/c99991X5eps3b+bmm2/mww8/BOD8+fNER0eTlpZGamoqAPv27SMxMZEDBw6Qn59Pz549K1Q3q6i+szqcv78/06ZNY9WqVYwZM4Ynn3zSMWX13nvvXdMoR7n+8SmnYAzccEM9/OrVg40bYd48+Pln+O47WLVKX0BTqk1VlLlcoVu3bsycOZNZs2bxwAMPcM8995QSsPnkk08YPnw4wfaquMpy9ldUvzx1uPHjx3Py5ElOnDjBqVOnaNasGaGhodXqm3J94lGnICKDgDcAP+AdY8wrJY4HAsuBXsBpYLQxJsMTthTFFBoVXIIZs2H3buvAnXfCc8+pQ1CuSzp37sy+ffvYuHEjzz77LDExMWUmQ6uqzGN59ctThwMYNWoUSUlJ/Oc//2HMmDFVak+pPXgspiAifsBCYDDQFYgVkZIqM5OAs8aYjsAC4M+esicn2yDnztHq7XjLITRuDHFx8Ne/QjUFPhSlJK4oc7nCiRMnCA4OZty4ccycOZP9+/fTqFGjYjKVffr0Yd26deTk5HDhwgX+6Zyttwwqql+eOhxYOsyJiYkkJSUxatSoavdNuT7x5EjhDuBrY8wxABFJBB4E0p3qPAjE2Z+TgDdFRIwHlH8uX8ij3ukzBP/iIvTvbyWwa9HC3c0o1wmBgYFkZ2e79XquUBRTKElZMYXY2Fh27tzJTz/9REhICC+99BKTJk0qVueLL77g6aefpl69evj7+7N48WJatGjB3XffTWRkJIMHD+a1115j9OjRREVF0bZtW+655x7H+UOGDOGdd94ppmzWs2fPcus7q8MVFhbi7+/PwoULadu2LREREVy4cIE2bdrQunXrCttQai8eU14TkVHAIGPMZHv/YSDaGPOEU500u06Wvf+NXeenEteaAkwBCA0N7VX05FIVnnsOdv7jR54b/gUR/zPqWrt1zdTzE9pGqBPyFKq8pihXuV6V18qatCzpgVypgzHmLeAtsOQ4r8WYOXOAOTcBN13L6YqiKD6BJ99TyAKcXwENAU6UV0dE6gNNgDMetElRFEWpAE86hb1AJxEJE5EAYAywoUSdDcAj9udRwHZPxBMU30B/OopS/f8DjzkFY0w+8ATwEfAl8J4x5pCI/ElEihZGvwu0EJGvgaeAZzxlj1K3CQoK4vTp0+oYFJ/GGMPp06erpSzpsUCzp7jttttMSkpKTZuhXGdcuXKFrKwsLhflSFcUHyUoKIiQkBD8S2jGXw+BZkXxGv7+/oSFhdW0GYpS6/GZhHiKoihK5ahTUBRFURyoU1AURVEc1LpAs4icAqr+SrPFjcBPldaqW2iffQPts29QnT63Nca0rKxSrXMK1UFEUlyJvtcltM++gfbZN/BGn3X6SFEURXGgTkFRFEVx4GtO4a2aNqAG0D77Btpn38DjffapmIKiKIpSMb42UlAURVEqQJ2CoiiK4qBOOgURGSQiR0TkaxEplXlVRAJFZI19/DMRaed9K92LC31+SkTSReSgiGwTkbY1Yac7qazPTvVGiYgRkVq/fNGVPovIQ/bf+pCIrPa2je7Ghd92qIjsEJED9u97SE3Y6S5EZKmInLSVKcs6LiISb38fB0Wkp1sNMMbUqQ3wA74B2gMBwL+BriXqTAOW2J/HAGtq2m4v9LkfEGx//q0v9Nmu1wj4F5AM3FbTdnvh79wJOAA0s/db1bTdXujzW8Bv7c9dgYyatruafe4D9ATSyjk+BNiEpVx5J/CZO9uviyOFO4CvjTHHjDF5QCLwYIk6DwJ/tz8nAQNEpCxp0NpCpX02xuwwxhQp2SdjKeHVZlz5OwP8H+BVoC7k1Halz48BC40xZwGMMSe9bKO7caXPBmhsf25CaYXHWoUx5l9UrED5ILDcWCQDTUWktbvar4tOoQ2Q6bSfZZeVWcdYYkDngRZesc4zuNJnZyZhPWnUZirts4jcCtxijPnAm4Z5EFf+zp2BziKyS0SSRWSQ16zzDK70OQ4YJyJZwEbgf3nHtBqjqv/vVaIu6imU9cRfct2tK3VqEy73R0TGAbcB93rUIs9TYZ9FpB6wAJjgLYO8gCt/5/pYU0h9sUaDn4hIpDHmnIdt8xSu9DkWWGaMmS8idwEr7D4Xet68GsGj96+6OFLIAm5x2g+h9HDSUUdE6mMNOSsarl3vuNJnRGQg8Dww1BiT6yXbPEVlfW4ERAI7RSQDa+51Qy0PNrv6215vjLlijPkWOILlJGorrvR5EvAegDFmDxCElTiuruLS//u1Uhedwl6gk4iEiUgAViB5Q4k6G4BH7M+jgO3GjuDUUirtsz2V8jcsh1Db55mhkj4bY84bY240xrQzxrTDiqMMNcbUZi1XV37b72MtKkBEbsSaTjrmVSvdiyt9/h4YACAiXbCcwimvWuldNgDj7VVIdwLnjTE/uOvidW76yBiTLyJPAB9hrVxYaow5JCJ/AlKMMRuAd7GGmF9jjRDG1JzF1cfFPr8GNATW2jH1740xQ2vM6GriYp/rFC72+SMgRkTSgQLgaWPM6Zqzunq42Oc/AG+LyO+xplEm1OaHPBFJwJr+u9GOk7wI+AMYY5ZgxU2GAF8D2cCjbm2/Fn93iqIoipupi9NHiqIoyjWiTkFRFEVxoE5BURRFcaBOQVEURXGgTkFRFEVxoE5Bue4QkQIRSXXa2lVQt1152SSr2OZOOxPnv+0UEeHXcI2pIjLe/jxBRG52OvaOiHR1s517RSTKhXOeFJHg6rat+AbqFJTrkRxjTJTTluGldscaY3pgJUt8raonG2OWGGOW27sTgJudjk02xqS7xcqrdi7CNTufBNQpKC6hTkGpFdgjgk9EZL+9/Y8y6kSIyOf26OKgiHSyy8c5lf9NRPwqae5fQEf73AF2nv4v7Dz3gXb5K3JVn2KeXRYnIjNFZBRWfqlVdpsN7Cf820TktyLyqpPNE0Tkr9do5x6cEqGJyGIRSRFLR+Elu+x3WM5ph4jssMtiRGSP/T2uFZGGlbSj+BDqFJTrkQZOU0fr7LKTwK+MMT2B0UB8GedNBd4wxkRh3ZSz7LQHo4G77fICYGwlmsfV1gAAAo5JREFU7f8a+EJEgoBlwGhjTDesDAC/FZHmwHAgwhjTHZjtfLIxJglIwXqijzLG5DgdTgJGOO2PBtZco52DsNJaFPG8MeY2oDtwr4h0N8bEY+XF6WeM6WenvvjfwED7u0wBnqqkHcWHqHNpLpQ6QY59Y3TGH3jTnkMvwMrpU5I9wPMiEgL8tzHmqIgMAHoBe+30Hg2wHExZrBKRHCADK/1yOPCtMeYr+/jfgenAm1j6DO+IyIeAy6m5jTGnROSYnbPmqN3GLvu6VbHzBqy0D86qWw+JyBSs/+vWWIIzB0uce6ddvstuJwDre1MUQJ2CUnv4PfAj0ANrhFtKNMcYs1pEPgPuBz4SkclYaYb/box51oU2xjonzBORMjU27Hw8d2AlYRsDPAH0r0Jf1gAPAYeBdcYYI9Yd2mU7sRTIXgEWAiNEJAyYCdxujDkrIsuwEsOVRIAtxpjYKtir+BA6faTUFpoAP9g58h/Gekouhoi0B47ZUyYbsKZRtgGjRKSVXae5uK5PfRhoJyId7f2HgY/tOfgmxpiNWEHcslYAXcBK310W/w0Mw9IBWGOXVclOY8wVrGmgO+2pp8bAJeC8iNwEDC7HlmTg7qI+iUiwiJQ16lJ8FHUKSm1hEfCIiCRjTR1dKqPOaCBNRFKBX2JJFqZj3Tz/n4gcBLZgTa1UijHmMlYGyrUi8gVQCCzBusF+YF/vY6xRTEmWAUuKAs0lrnsWSAfaGmM+t8uqbKcdq5gPzDTG/BtLm/kQsBRrSqqIt4BNIrLDGHMKa2VUgt1OMtZ3pSiAZklVFEVRnNCRgqIoiuJAnYKiKIriQJ2CoiiK4kCdgqIoiuJAnYKiKIriQJ2CoiiK4kCdgqIoiuLg/wOaPiqaGXVRpwAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "tprs = []\n",
    "aucs = []\n",
    "mean_fpr = np.linspace(0, 1, 100)\n",
    "\n",
    "# 统计每次结果，并绘制相应的ROC曲线\n",
    "i = 0\n",
    "for train, test in cv.split(X, y):\n",
    "    probas_ = classifier.fit(X[train], y[train]).predict_proba(X[test])\n",
    "    # Compute ROC curve and area the curve\n",
    "    fpr, tpr, thresholds = roc_curve(y[test], probas_[:, 1])\n",
    "    tprs.append(interp(mean_fpr, fpr, tpr))\n",
    "    tprs[-1][0] = 0.0\n",
    "    roc_auc = auc(fpr, tpr)\n",
    "    aucs.append(roc_auc)\n",
    "    plt.plot(fpr, tpr, lw=1, alpha=0.3,\n",
    "             label='ROC fold %d (AUC = %0.2f)' % (i, roc_auc))\n",
    "\n",
    "    i += 1\n",
    "plt.plot([0, 1], [0, 1], linestyle='--', lw=2, color='r',\n",
    "         label='Chance', alpha=.8)\n",
    "\n",
    "# 计算平均结果，绘制平均ROC曲线\n",
    "mean_tpr = np.mean(tprs, axis=0)\n",
    "mean_tpr[-1] = 1.0\n",
    "mean_auc = auc(mean_fpr, mean_tpr)\n",
    "std_auc = np.std(aucs)\n",
    "plt.plot(mean_fpr, mean_tpr, color='b',\n",
    "         label=r'Mean ROC (AUC = %0.2f $\\pm$ %0.2f)' % (mean_auc, std_auc),\n",
    "         lw=2, alpha=.8)\n",
    "\n",
    "# 将均值线上下一个标准差内的区域上色\n",
    "std_tpr = np.std(tprs, axis=0)\n",
    "tprs_upper = np.minimum(mean_tpr + std_tpr, 1)\n",
    "tprs_lower = np.maximum(mean_tpr - std_tpr, 0)\n",
    "plt.fill_between(mean_fpr, tprs_lower, tprs_upper, color='grey', alpha=.2,\n",
    "                 label=r'$\\pm$ 1 std. dev.')\n",
    "\n",
    "plt.xlim([-0.05, 1.05])\n",
    "plt.ylim([-0.05, 1.05])\n",
    "plt.xlabel('False Positive Rate')\n",
    "plt.ylabel('True Positive Rate')\n",
    "plt.title('Receiver operating characteristic')\n",
    "plt.legend(loc=\"lower right\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
